package edu.cmu.ibill.controller;

import java.io.File;
import java.io.IOException;

import javax.servlet.*;
import javax.servlet.http.*;

import edu.cmu.ibill.model.Model;

import edu.cmu.ibill.databeans.*;

/**
 * 
 * @author Yunkai Zhang 15-637
 */

public class Controller extends HttpServlet {

	public void init() throws ServletException {
		Model model = new Model(getServletConfig());

		Action.add(new RegisterAction(model));
		Action.add(new LoginAction(model));
		Action.add(new LogoutAction(model));
		Action.add(new AccountSettingAction(model));
		Action.add(new AddBillAction(model));
		Action.add(new UpdateBillAction(model));
		Action.add(new RemoveBillAction(model));
		Action.add(new AddSharedBillAction(model));
		Action.add(new ShowAllBillAction(model));
		Action.add(new ShowDetailedBillAction(model));
		Action.add(new ShowReportAction(model));
		Action.add(new AddDebtAction(model));
		Action.add(new AddPaymentAction(model));
		Action.add(new AddSharedUserAction(model));
		Action.add(new ShowAccountSummaryAction(model));
		Action.add(new ChangePasswordAction(model));
						
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doGet(request, response);
	}

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		String nextPage = performTheAction(request);
		if (nextPage.startsWith("#data#")) {
			nextPage = nextPage.replaceAll("#data#", "");
			response.getWriter().println(nextPage);
		} else
			sendToNextPage(nextPage, request, response);
	}

	/*
	 * Extracts the requested action and (depending on whether the user is
	 * logged in) perform it (or make the user login).
	 * 
	 * @param request
	 * 
	 * @return the next page (the view)
	 */
	private String performTheAction(HttpServletRequest request) {
		HttpSession session = request.getSession(true);
		String servletPath = request.getServletPath();
		User user = (User) session.getAttribute("user");
		String action = getActionName(servletPath);

		if (user != null && action.equals("showbookmarks.do"))
			return Action.perform("showbookmarks.do", request);

		if (user != null && action.equals("start")) {
			return Action.perform("showbookmarks.do", request);
		}

		if (user != null && action.equals("login.do"))
			return Action.perform("showbookmarks.do", request);

		if (user != null && action.equals("register.do"))
			return Action.perform("showbookmarks.do", request);

		if (action.equals("register.do") || action.equals("login.do")) {
			// Allow these actions without logging in
			return Action.perform(action, request);
		}

		if (user == null) {
			// If the user hasn't logged in, direct him to the login page
			return Action.perform("login.do", request);
		}

		return Action.perform(action, request);
	}

	/*
	 * If nextPage is null, send back 404 If nextPage starts with a '/',
	 * redirect to this page. In this case, the page must be the whole servlet
	 * path including the webapp name Otherwise dispatch to the page (the view)
	 * This is the common case Note: If nextPage equals "image", we will
	 * dispatch to /image. In the web.xml file, "/image" is mapped to the
	 * ImageServlet will which return the image bytes for display.
	 */
	private void sendToNextPage(String nextPage, HttpServletRequest request,
			HttpServletResponse response) throws IOException, ServletException {
		// System.out.println("nextPage="+nextPage);

		if (nextPage == null) {
			response.sendError(HttpServletResponse.SC_NOT_FOUND,
					request.getServletPath());
			return;
		}

		String redirect = (String) request.getAttribute("redirect");

		if (redirect != null && redirect.equals("true")) {
			request.setAttribute("redirect", "false");
			response.sendRedirect(nextPage);
			return;
		}

		if (nextPage.charAt(0) == '/') {
			String host = request.getServerName();
			String port = ":" + String.valueOf(request.getServerPort());
			if (port.equals(":80"))
				port = "";
			response.sendRedirect("http://" + host + port + nextPage);
			return;
		}

		RequestDispatcher d = request.getRequestDispatcher("/" + nextPage);
		d.forward(request, response);
	}

	/*
	 * Returns the path component after the last slash removing any "extension"
	 * if present.
	 */
	private String getActionName(String path) {
		// We're guaranteed that the path will start with a slash
		int slash = path.lastIndexOf('/');
		return path.substring(slash + 1);
	}
}
